#include "ModbusClient.h"
#include <QDebug>
#include <FloraLogger.h>


ModbusClient::ModbusClient(QObject *parent)
    : QThread(parent), ctx(nullptr) {}

ModbusClient::~ModbusClient() {
    stopPolling();
    if (ctx) {
        modbus_close(ctx);
        modbus_free(ctx);
    }
}

bool ModbusClient::init(ModbusMode mode, const QString &addressOrPort, int baudOrPort) {
    this->mode = mode;

    if (mode == RTU) {
        ctx = modbus_new_rtu(addressOrPort.toStdString().c_str(), baudOrPort, 'N', 8, 1);
    } else if (mode == TCP) {
        ctx = modbus_new_tcp(addressOrPort.toStdString().c_str(), baudOrPort);
    }
    modbus_set_response_timeout(ctx,3,0);
    if (!ctx) {
        emit errorOccurred("Failed to create Modbus context");
        return false;
    }

    if (modbus_connect(ctx) == -1) {
        emit errorOccurred("Modbus connection failed");
        modbus_free(ctx);
        ctx = nullptr;
        return false;
    }
    ModbusRequest temp;
    temp.device_id =1;
    temp.addres=1;
    temp.len=5;
    temp.opType = ReadCoils;
    addRequest(temp);
    start();  // 启动线程
    return true;
}

void ModbusClient::run() {
    uint8_t request_count = 0;
    ModbusRequest temp_modbusRequest;
    ModbusRequest temp_command;
    uint8_t request_amount =0;
    int rec = 0;
    while (true) {
        temp_command.opType = NONE_OP;
        QMutexLocker locker(&mutex);
        // 优先处理命令队列中的命令
        if (!commandQueue.isEmpty()) {
            temp_command = commandQueue.dequeue();
        }
        locker.unlock();
        if(temp_command.opType != NONE_OP)
        {
            switch(temp_command.opType)
            {
            case WriteHoldingRegisters:
                modbus_set_slave(ctx,temp_command.device_id);
                rec = modbus_write_registers(ctx,temp_command.addres,temp_command.len,temp_command.date);
                break;
            case WriteSingleCoil:
                modbus_set_slave(ctx,temp_command.device_id);
                rec = modbus_write_bit(ctx,temp_command.addres,temp_command.date_8[0]);
                break;
            case WriteSingleCoilS:
                modbus_set_slave(ctx,temp_command.device_id);
                rec = modbus_write_bits(ctx,temp_command.addres,temp_command.len,temp_command.date_8);
                break;
            }
            if(rec <= 0)
            {
                temp_command.opResult = false;
                LOG_DEBUG<<"写失败";
            }
            else
            {
                temp_command.opResult = true ;
                LOG_DEBUG<<"写成功";
            }
            emit request_receive_data(temp_command);
        }
        //请求队列
        mutex.lock();
        if(request_count >= requests.size() )
        {
            request_count = 0;
        }
        if(requests.size() >0)
        {
            temp_modbusRequest = requests[request_count];
            request_amount = requests.size();
            request_count ++;
        }
        else
        {
            request_amount = 0;
        }

        mutex.unlock();
        if(request_amount >0)
        {
            switch(temp_modbusRequest.opType)
            {
            case ReadHoldingRegisters:
                modbus_set_slave(ctx,temp_modbusRequest.device_id);
                rec = modbus_read_registers(ctx,temp_modbusRequest.addres,temp_modbusRequest.len,temp_modbusRequest.date);
                break;
            case ReadCoils:
                modbus_set_slave(ctx,temp_modbusRequest.device_id);
                rec = modbus_read_bits(ctx,temp_modbusRequest.addres,temp_modbusRequest.len,temp_modbusRequest.date_8);
                break;

            }
            if(rec <= 0)
            {

                temp_modbusRequest.opResult = false;
                LOG_DEBUG<<"询问失败";

            }
            else
            {
                temp_modbusRequest.opResult = true ;
                LOG_DEBUG<<"询问成功:"<<rec;
                for(int i=0; i< rec; i++)
                {
                    LOG_DEBUG<<"地址:"<<temp_modbusRequest.addres+i<<"数据:"<<temp_modbusRequest.date_8[i];
                }

            }
            emit request_receive_data(temp_modbusRequest);
        }
    }
}

void ModbusClient::stopPolling() {
    mutex.lock();
    quit();  // 停止线程
    mutex.unlock();
    wait();  // 等待线程结束
}

void ModbusClient::sendCommand(const ModbusRequest &request) {
    QMutexLocker locker(&mutex);
    commandQueue.enqueue(request);  // 将命令添加到命令队列中
    //commandCondition.wakeOne();  // 唤醒线程处理命令
}

void ModbusClient::sendTestComand()
{
    ModbusRequest temp;
    temp.device_id =1;
    temp.addres =1;
    temp.date[0]=200;
    temp.date_8[0] = 1;
    temp.date_8[1] = 1;
    temp.len =2;
    temp.opType =WriteSingleCoil;
    sendCommand(temp);
}

void ModbusClient::addRequest(const ModbusRequest &request) {
    QMutexLocker locker(&mutex);
   // requests.append(request);
}
